/*
 * @Author: ischen.x ischen.x@foxmail.com
 * @Date: 2025-01-03 14:51:37
 * @LastEditors: ischen.x ischen.x@foxmail.com
 * @LastEditTime: 2025-03-04 15:26:17
 * 
 * Copyright (c) 2025 by fhchengz, All Rights Reserved. 
 */
#ifndef __TLV_H
#define __TLV_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <stdlib.h>

#define FIELD_TYPE_HEAD     USE_UINT8_T
#define FIELD_TYPE_TAG      USE_UINT8_T
#define FIELD_TYPE_LENGTH   USE_UINT8_T
#define FIELD_TYPE_CRC      USE_UINT8_T
#define FIELD_TYPE_VALUE    USE_UINT8_T

// 根据宏定义选择不同的字段类型
#if FIELD_TYPE_HEAD == USE_UINT8_T
    typedef uint8_t head_type;
#elif FIELD_TYPE_HEAD == USE_UINT16_T
    typedef uint16_t head_type;
#elif FIELD_TYPE_HEAD == USE_UINT32_T
    typedef uint32_t head_type;
#else
    #error "Unsupported head type"
#endif

#if FIELD_TYPE_TAG == USE_UINT8_T
    typedef uint8_t tag_type;
#elif FIELD_TYPE_TAG == USE_UINT16_T
    typedef uint16_t tag_type;
#elif FIELD_TYPE_TAG == USE_UINT32_T
    typedef uint32_t tag_type;
#else
    #error "Unsupported tag type"
#endif

#if FIELD_TYPE_LENGTH == USE_UINT8_T
    typedef uint8_t length_type;
#elif FIELD_TYPE_LENGTH == USE_UINT16_T
    typedef uint16_t length_type;
#elif FIELD_TYPE_LENGTH == USE_UINT32_T
    typedef uint32_t length_type;
#else
    #error "Unsupported length type"
#endif

#if FIELD_TYPE_CRC == USE_UINT8_T
    typedef uint8_t crc_type;
#elif FIELD_TYPE_CRC == USE_UINT16_T
    typedef uint16_t crc_type;
#elif FIELD_TYPE_CRC == USE_UINT32_T
    typedef uint32_t crc_type;
#else
    #error "Unsupported crc type"
#endif

// 根据宏定义的类型，选择 value 类型
#if FIELD_TYPE_VALUE == USE_UINT8_T
    typedef uint8_t value_type;
#elif FIELD_TYPE_VALUE == USE_UINT16_T
    typedef uint16_t value_type;
#elif FIELD_TYPE_VALUE == USE_UINT32_T
    typedef uint32_t value_type;
#else
    #error "Unsupported value type"
#endif

// 错误代码宏定义
#define TLV_PACK_SUCCESS    0    // 成功
#define TLV_PACK_ERR_MEMORY -1   // 内存分配失败
#define TLV_PACK_ERR_NULL   -2   // 空指针错误
#define TLV_PACK_ERR_CRC    -3   // CRC 计算失败
#define TLV_PACK_ERR_BUFF   -4   // 缓冲区溢出

typedef int (*tlv_crc_t)(uint8_t *data, uint8_t len);

typedef struct _tlv {
    head_type head;            // 根据宏定义的类型
    tag_type tag;              // 根据宏定义的类型
    length_type length;        // 根据宏定义的类型
    value_type *value;         // 根据宏定义的类型
    crc_type crc;              // 根据宏定义的类型
} tlv_frame_t;


int tlv_set_crc_function(tlv_crc_t tlv_fun);
int tlv_pack(head_type head, tag_type tag, uint8_t *value, length_type value_len, uint8_t **output_buffer, uint8_t *out_len);
int tlv_process_stream(uint8_t *buffer, int buffer_len, head_type head);
int tlv_unpack(uint8_t *buffer, uint8_t buffer_len, tlv_frame_t **frame);


#define  TLV_BUFF_LEN          (100)     //定义最大接收字节数
#define  TLV_BUFF_SUCCESS      1     
#define  TLV_BUFF_ERR          0   
#define  MAX_BUF_LEN           50


typedef enum {
    STATE_SEARCH_HEADER,
    STATE_READ_TAG,
    STATE_READ_LENGTH,
    STATE_READ_DATA,
    STATE_READ_CRC
} ParserState;


typedef struct
{
    uint16_t Head;           
    uint16_t Tail;
    uint16_t Lenght;
    uint8_t  Tlv_data[TLV_BUFF_LEN];
	
    uint8_t recv_buf[MAX_BUF_LEN];
    uint8_t buf_index;
    length_type expected_length;
    uint8_t byte;
    ParserState state;
    head_type header;
	
}TlvBuff_t;

void tlv_buff_init(TlvBuff_t *tlvbuff,head_type header);
uint8_t write_tlv_buff(TlvBuff_t *tlvbuff, uint8_t data);
uint8_t read_tlv_buff(TlvBuff_t *tlvbuff, uint8_t *rData);
int tlv_parsing(TlvBuff_t *tlvbuff,uint8_t *returnbuff);
#ifdef __cplusplus
}
#endif

#endif /* __TLV_H */

